using System;
using System.Collections.Generic;
using System.Text;
using ImagesMath;

namespace Graphics.Geometries
{
    public class Sphere : Form
    {


        // /*
        // *
        // *  Ellipsoide equation :
        // *
        // *    F(x, y, z) = x^2 + y^2 + z^2 - 1.0;
        // *
        // *    After substituting the ray equation in the quadric equation,
        // *      we have :
        // *        Aq * t^2 + Bq * t + Cq = 0
        // *
        // *      with
        // *        Aq = Xd^2 + Yd^2 + Zd^2;
        // *        Bq = 2.0 * (Xd * Xo + Yd * Yo + Zd * Zo);
        // *        Cq = Xo^2 + Yo^2 + Zo^2 - 1.0;
        // *
        // *        If Aq <> 0
        // *          t = (-Bq +- sqrt(Bq^2 - 4.0*Aq*Cq)) / 2.0*Aq
        // *        Else
        // *          t = -Cq / Bq
        // *
        // *    Normal(x, y, z) = 
        // *      | 2.0 * x
        // *      | 2.0 * y
        // *      | 2.0 * z
        // *
        // */

        public Sphere() : base()
        {

        }

        public override bool FirstIntersection(ref Ray ray,ref Intersection inter)	// Rempli inter.t et renvoie true si 1 intersection
        {
            double Xo = ray.Origin.X;
            double Xd = ray.Direction.X;
            double Yo = ray.Origin.Y;
            double Yd = ray.Direction.Y;
            double Zo = ray.Origin.Z;
            double Zd = ray.Direction.Z;

            double Aq = Xd * Xd + Yd * Yd + Zd * Zd;
            double Bq = (Xd * Xo + Yd * Yo + Zd * Zo);
            double Cq = Xo * Xo + Yo * Yo + Zo * Zo - 1.0;

            if (Aq != 0)
            {
                //t = (-Bq +- sqrt(Bq^2 - 4.0*Aq*Cq)) / 2.0*Aq
                if ((Bq * Bq - Aq * Cq) != 0)
                {
                    double Bq2 = Bq * Bq;
                    double AqCq = Aq * Cq;
                    double sqr = Bq2 - AqCq;

                    //if (sqr < 0)
                    //{
                    //    sqr = -sqr;
                    //}

                    if (sqr > 0)
                    {
                        Console.WriteLine("Prend-moi toute !");
                    }


                    double a = Math.Sqrt(sqr);

                    double t1 = (-Bq + a) / Aq;
                    double t2 = (-Bq - a) / Aq;

                    if (t2 > ImageMath.EPS)
                    {
                        inter.T = t2;
                        return true;
                    }

                    else if (t1 > ImageMath.EPS)
                    {
                        inter.T = t1;
                        return true;
                    }

                    else
                        return false;
                }
                else
                    return false;
            }
            return false;
        }
        public override VR3 Normal(PR3 p, ref Ray ray) // Renvoi normale locale
        {
            return (new VR3(p)).normalize();
        }
        public override bool IsInside(PR3 p)
        {
            return false;
        }


        // jo + malou = love  :)


        //bool CSphere::FirstIntersection( const CRay & ray, CIntersection & inter )
        //    {

        //        double Xo = ray.Origin().x;  
        //        double Xd = ray.Direction().x;			
        //        double Yo = ray.Origin().y;  
        //        double Yd = ray.Direction().y;
        //        double Zo = ray.Origin().z;  
        //        double Zd = ray.Direction().z;

        //        double Aq = Xd*Xd + Yd*Yd +Zd*Zd;
        //        double Bq = (Xd * Xo + Yd * Yo + Zd * Zo);
        //        double Cq = Xo*Xo + Yo*Yo +Zo*Zo - 1.0;		

        //        if (Aq != 0)
        //        {
        //                if ( (Bq*Bq - Aq*Cq) != 0 )
        //                {
        //                double t1 = (-Bq + sqrt(Bq*Bq - Aq*Cq)) / Aq;
        //                double t2 = (-Bq - sqrt(Bq*Bq - Aq*Cq)) / Aq;

        //                if ( t2 > EPS )
        //                {
        //                    inter.t = t2;
        //                    return true;
        //                }

        //                else if ( t1 > EPS)
        //                {
        //                    inter.t = t1;
        //                    return true;
        //                }

        //                else
        //                    return false;
        //            }
        //            else
        //                return false;	
        //        }
        //    }


        //vR3  CSphere::Normal( const pR3 & p, const CRay & ray )
        //    {
        //        return ( vR3(p) ).normalize();
        //    }

        //    bool CSphere::IsInside( const pR3 & p )
        //    {
        //        return true;
        //    }

        //string CSphere::getName()const{return _nomObjet;}
        //void CSphere::setName(string name){_nomObjet=name;}		
			


    }
}
